

/**
 * 
 xxx {
 	// xxx
	led-ctl-gpios =<&gpio3 RK_PB1 GPIO_ACTIVE_HIGH
			>;
 };
           
 * 
 * 
 * */

#include <linux/gpio/consumer.h>
#include <linux/string.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/device.h>



#define MAX_GPIO_COUNT 12
struct  led_group_desc{
	struct gpio_descs *descs;
	int *values;
	int n;
};

static struct led_group_desc* pleds;

int led_group_control(int pos, int max_pos)
{
	int count;
	int n = pleds->n;
	int i;
	// we should map pos to [0, n)
	count = n * pos * 10 / max_pos;
	if(count %10 > 5){
		count = count / 10 + 1;
	}else{
		count /= 10;
	}
	if(count >= n)
		count = n;
	for(i=0; i<count; i++)
		pleds->values[i] = 1;
	for(; i<n; i++)
		pleds->values[i] = 0;
	gpiod_set_array_value(n, pleds->descs->desc, pleds->values);
	return 0;
}

// 	int gpiod_count(struct device *dev, const char *con_id);
//devm_gpiod_get_array_optional(struct device *dev, const char *con_id,
//			      enum gpiod_flags flags);
//void gpiod_set_array_value(unsigned int array_size,
//			   struct gpio_desc **desc_array, int *value_array);
int led_ctl_parse_dt(struct device *dev)
{
	int n;
	int err;
	pleds = devm_kzalloc(dev, sizeof(struct  led_group_desc), GFP_KERNEL);
	if(!pleds)
		goto err_nomem;
	n = gpiod_count(dev, "led-ctl");
	if(n <= 0){
		dev_err(dev, "gpiod_count err: %d", n);
		return -ENODEV;
	}
	pleds->n = n;
	pleds->values = devm_kzalloc(dev, sizeof(int) * n, GFP_KERNEL);
	if(!pleds->values)
		goto err_nomem;
	pleds->descs = devm_gpiod_get_array_optional(dev, "led-ctl", GPIOD_OUT_LOW);
	err = PTR_ERR_OR_ZERO(pleds->descs);
	if(err){
		dev_err(dev, "devm_gpiod_get_array_optional fail, err=%d",err);
		return err;
	}
	dev_info(dev, "%s OK\n", __func__);
	return 0;
err_nomem:
	return -ENOMEM;
}
